<?php

/**
 * This file is part of the Codizer package.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @copyright   Copyright (c) 2010 Advisa (http://www.advisa.fr)
 * @author      Codizer Core Team <team@codizer.org>
 * @package     Codizer
 */

require(FRAMEWORK_HOME.DS."template".DS."smarty".DS."Smarty.class.php");

class f_template_TemplateSmarty extends Smarty
{
	private $templateFile;
	private $discriminator = array();
	private $frontTemplate;
	private $backTemplate;
    private $cacheGroup;
    private $moduleName;

	private $displayTemplatePath = false;

	/**
	 * Constructor
	 *
	 */
	private function __construct()
	{			
		$config = f_loader_Config::getInstance()->getParameters("default");

		if($config['loggingLevel'] == "DEBUG")
		{
		    $this->displayTemplatePath = true;
		}

		ini_set("include_path", BASE_DIR);
			
        $this->caching = false;
        if(isset($config['smartyCache']) && $config['smartyCache'] == true)
        {
            $this->caching = true;
        }
		
		$baseDir = WEBAPP_DIR.DS;
		
		$this->frontTemplate = $config['frontTheme'];
		$this->backTemplate = $config['backTheme'];
		$this->template_dir = $baseDir.'templates';
		$this->cache_dir = $baseDir.'cache'.DS."html";
		$this->plugins_dir[] = FRAMEWORK_HOME.DS."template".DS."smartyplugins";
		
		if(is_dir(WEBAPP_DIR.DS."smartyplugins"))
		{
			$this->plugins_dir[] = WEBAPP_DIR.DS."smartyplugins";
		}
		
		$this->compile_dir = $baseDir.'cache'.DS.'templates_c';
	}
	
	/**
	 * Get the current instance or create a new instance of f_template_Template
	 *
	 * @return f_template_Template
	 */
	public static function getInstance()
	{
		return new self();
	}
	
	/**
	 * Disable cache
	 *
	 * @return f_template_Template
	 */
	public function disableCache()
	{
		$this->caching = false;
		return $this;
	}

	/**
	 * Set other delimiter in smarty
	 *
	 * @return f_template_Template
	 */
    public function setDelimiter($left = '{', $right = '}')
    {
        $this->left_delimiter = $left;
        $this->right_delimiter = $right;
        return $this;
    }
	
	/**
	 * Set the template file
	 *
	 * @param string $templateFile
	 * 
	 * @return f_template_TemplateSmarty
	 */
	public function setTemplate($templateFile)
	{
		if(is_file(realpath($templateFile)))
		{
			$this->templateFile = $templateFile;	
		}
		else
		{
			throw new Exception("Template file not found :".$templateFile);
		}
		return $this;
	}

    /**
     * Is template in webapp ?
     *
     * @return boolean
     */
    public function inWebapp()
    {
        return strstr($this->templateFile, 'webapp'.DS.'modules');
    }
	
	/**
	 * Return the template full path
	 *
	 * @return string
	 */
	public function getTemplate()
	{
		return $this->templateFile;
	}

    /**
     * @param string $moduleName
     * @return f_template_TemplateSmarty
     */
    public function setModuleName($moduleName)
    {
        $this->moduleName = $moduleName;
        return $this;
    }

    /**
     * Return the module name (if setted)
     *
     * @return string|null
     */
    public function getModuleName()
    {
        return $this->moduleName;
    }
		
	/**
	 * Set module template
	 *
	 * @param string $moduleName
	 * @param string $templateName
	 * 
	 * @return f_template_TemplateSmarty
	 */
	public function setModuleTemplate($moduleName, $templateName)
	{
		$path = DS.$moduleName.DS."templates".DS.$templateName;

        $this->moduleName = $moduleName;
		
		if(is_file(WEBAPP_MODULES_DIR.$path))
		{
			$file = WEBAPP_MODULES_DIR.$path;
		}
		else
		{
			if(is_file(MODULES_DIR.$path))
			{
				$file = MODULES_DIR.$path;
			}
			else
			{
				throw new Exception("Template ".$path." not found !");
			}
		}
		
		$this->setTemplate($file);
		return $this;
	}

	/**
	 * Add a cache discriminator
	 *
	 * @param mixed $discriminator
	 * @return f_template_AbstractTemplate
	 */
	public function addCacheDiscriminator($discriminator, $cacheGroup = null)
	{
        if(!is_null($cacheGroup) && is_string($cacheGroup))
        {
            $this->cacheGroup = $cacheGroup;
        }

		if(is_string($discriminator) || is_int($discriminator) || is_float($discriminator))
		{
			$this->discriminator[] = $discriminator;
		}
		if(is_array($discriminator) && count($discriminator) >=1 )
		{
			$this->discriminator[] = join("-", $discriminator);
		}
		if(is_object($discriminator) && method_exists($discriminator, "getId"))
		{
			$this->discriminator[] = "docId".$discriminator->getUniqueId();
		}

		return $this;
	}

    public function setCacheGroup($value)
    {
        $this->cacheGroup = $value;
    }

	/**
	 * Get discriminator string
	 *
	 * @return string
	 */
	public function getDiscriminator()
	{
        $discriminator = "";

        if(!is_null($this->cacheGroup))
        {
            $discriminator .= $this->cacheGroup;
            if(substr($discriminator, -1, 1) != "|")
            {
                $discriminator .= "|";
            }
        }

        if(count($this->discriminator) > 0)
        {
            $discriminator .= join("-", $this->discriminator);
        }
        else
        {
            $discriminator = substr($discriminator, 0, strlen($discriminator) - 1);
        }

		return $discriminator;
	}

    /**
     * Clean up current template cache file
     */
    public function clearTemplateCache()
    {
        if($this->is_cached($this->getTemplate(), $this->getDiscriminator()))
        {
            $this->clear_cache($this->getTemplate(), $this->getDiscriminator());
        }
    }

	/**
	 * Render to the setted Template
	 *
	 * @return string
	 */
	public function render()
	{
		if(isset($_SERVER['HTTP_HOST'])) // check for CLI
		{           
            $this->assign('URL_ABSOLUTE', URL_ABSOLUTE);
            $this->assign('URL_RELATIVE', URL_RELATIVE);
		}
		
		$this->assign("MODULES_DIR", MODULES_DIR);
		$this->assign("WEBAPP_MODULES_DIR", WEBAPP_MODULES_DIR);
				
		$logger = f_logs_Logger::getInstance();

		$startTime = microtime(true);
		$content = $this->fetch($this->templateFile, $this->getDiscriminator());
		$time = round(microtime(true) - $startTime, 5);
		
		$logger->templateLog("Fetch template : ".$this->templateFile, $time);
		
		return $content;
	}

    /**
     *
     * @param string $value
     * @return f_template_TemplateSmarty
     */
    public function setFrontTheme($value)
    {
        $this->frontTemplate = $value;
        return $this;
    }

    /**
     *
     * @param string $value
     * @return f_template_TemplateSmarty
     */
    public function setBackTheme($value)
    {
        $this->backTemplate = $value;
        return $this;
    }
	
	/**
	 * Render to the setted Template
	 *
	 * @return string
	 */
	public function renderDisplay($tplPath = true)
	{
		if(isset($_SERVER['HTTP_HOST'])) // check for CLI
		{
            $this->assign('URL_ABSOLUTE', URL_ABSOLUTE);
            $this->assign('URL_RELATIVE', URL_RELATIVE);
		}
		
		$this->assign("MODULES_DIR", MODULES_DIR);
		$this->assign("WEBAPP_MODULES_DIR", WEBAPP_MODULES_DIR);
		$this->assign("FRONT_THEME", $this->frontTemplate);
		$this->assign("BACK_THEME", $this->backTemplate);	

		$logger = f_logs_Logger::getInstance();		
		
		$startTime = microtime(true);

		if($this->displayTemplatePath && $tplPath === true)
		{
		    $path = $this->getSimpleTemplatePath();
		    echo "\r\n<!-- START - ".$path." -->\r\n";
		    $this->display($this->templateFile, $this->getDiscriminator());
		    echo "\r\n<!-- END - ".$path." -->\r\n";
		}
		else
		{
		    $this->display($this->templateFile, $this->getDiscriminator());
		}

		$time = round(microtime(true) - $startTime, 5);
		
		$logger->templateLog("Render template : ".$this->templateFile, $time);
	}

	/**
	 * build a template render
	 *
	 * @param string $moduleTemplateName
	 * @param string $templateName
	 * @param array $assignments - array("assignVar" => "assignValues")
	 * @return string
	 */	
	public function buildTemplateRender($moduleTemplateName, $templateName, $assignments = array())
	{
		$this->disableCache();
		$this->setModuleTemplate($moduleTemplateName,$templateName);	
		
		foreach($assignments as $assignVar => $assignValues)
		{
			$this->assign($assignVar,$assignValues);	
		}
		
		$render = "";
		if($this->displayTemplatePath)
		{
		    $path = $this->getSimpleTemplatePath();
		    $render .= "\r\n<!-- START - ".$path." -->\r\n";
		    $render .= $this->render();
		    $render .= "\r\n<!-- END - ".$path." -->\r\n";
		}
		else
		{
		    $render = $this->render();
		}


		return $render;
	}

	private function getSimpleTemplatePath()
	{
	    list($prefix, $suffix) = explode("/modules", $this->templateFile);
	    $vars = explode("/", $prefix);
	    $modulePath = end($vars);
	    return $modulePath."/modules".$suffix;
	}
}

